package org.linlinjava.litemall.db.service;

import org.linlinjava.litemall.db.dao.StatMapper;
import org.linlinjava.litemall.db.util.CommonUtils;
import org.linlinjava.litemall.db.util.StatisticsFuncEnum;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.util.*;
import java.util.stream.Collectors;

@Service
public class StatService {
    @Resource
    private StatMapper statMapper;


    public List<Map<String, Object>> statUser() {
        return statMapper.statUser();
    }

    public List<Map<String, Object>> statOrder() {
        return statMapper.statOrder();
    }

    public List<Map<String, Object>> statGoods() {
        return statMapper.statGoods();
    }

    public List<Map<String, Object>> statGrouponsByActivityId(Integer activityId) {
        List<Map<String, Object>> totalMapList = statMapper.statGrouponsTotalByActivityId(activityId);
        List<Map<String, Object>> captainMemberMapList = statMapper.statGrouponsCaptainMemberByActivityId(activityId);
        List<String> dates = totalMapList.stream().map(it -> (String) it.get("date")).sorted().collect(Collectors.toList());

        List<Map<String, Object>> results = new ArrayList<>();
        for (int i = 0, index = dates.size(); i < index; i++) {
            String date = dates.get(i);
            Map<String, Object> result = new HashMap<>(16);

            Map<String, Object> totalMap = totalMapList.get(i);
            result.put("date", date);
            result.put("total", totalMap.get("total"));

            Map<String, Object> captainMemberMap = captainMemberMapList.get(i);
            if (i == 0) {
                result.put("captains", captainMemberMap.get("captains"));
                result.put("members", captainMemberMap.get("members"));
            } else {
                // 实现累计
                Integer accCaptains = 0;
                Integer accMembers = 0;
                for (int j = 0; j <= i; j++) {
                    Map<String, Object> less = captainMemberMapList.get(j);
                    BigDecimal captains = (BigDecimal) less.get("captains");
                    BigDecimal members = (BigDecimal) less.get("members");
                    accCaptains = CommonUtils.plus(accCaptains, Integer.valueOf(captains.toString()));
                    accMembers = CommonUtils.plus(accMembers, Integer.valueOf(members.toString()));
                }
                result.put("captains", accCaptains);
                result.put("members", accMembers);
            }
            results.add(result);
        }

        return results;
    }

    public List<Map<String, Object>> statStatisticsByActivityId(Byte relType, Integer relId) {
        return statMapper.statStatisticsByActivityId(relType, relId);
    }

    public List<Map<String, Object>> statOrderByActivityId(Integer activityId) {
        List<Map<String, Object>> ordersMapList = statMapper.statOrdersByActivityId(activityId);
        List<Map<String, Object>> orderDimensionMapList = statMapper.statOrderDimensionByActivityId(activityId);
        List<String> dates = ordersMapList.stream().map(it -> (String) it.get("date")).sorted().collect(Collectors.toList());

        List<Map<String, Object>> results = new ArrayList<>();
        for (int i = 0, index = dates.size(); i < index; i++) {
            String date = dates.get(i);
            Map<String, Object> result = new HashMap<>(16);

            Map<String, Object> totalMap = ordersMapList.get(i);
            result.put("date", date);
            result.put("orders", totalMap.get("orders"));

            Map<String, Object> orderDimensionMap = orderDimensionMapList.get(i);
            if (i == 0) {
                result.put("invailds", orderDimensionMap.get("invailds"));
                result.put("vailds", orderDimensionMap.get("vailds"));
                result.put("amount", orderDimensionMap.get("amount"));
                result.put("refundAmount", orderDimensionMap.get("refundAmount"));
            } else {
                // 实现累计
                Integer accInvailds = 0;
                Integer accVailds = 0;
                BigDecimal accAmount = new BigDecimal(0);
                BigDecimal accRefundAmount = new BigDecimal(0);
                for (int j = 0; j <= i; j++) {
                    Map<String, Object> less = orderDimensionMapList.get(j);
                    BigDecimal invailds = (BigDecimal) less.get("invailds");
                    BigDecimal vailds = (BigDecimal) less.get("vailds");
                    BigDecimal amount = (BigDecimal) less.get("amount");
                    BigDecimal refundAmount = (BigDecimal) less.get("refundAmount");
                    accInvailds = CommonUtils.plus(accInvailds, Integer.valueOf(invailds.toString()));
                    accVailds = CommonUtils.plus(accVailds, Integer.valueOf(vailds.toString()));
                    accAmount = CommonUtils.plus(accAmount, amount);
                    accRefundAmount = CommonUtils.plus(accRefundAmount, refundAmount);
                }
                result.put("invailds", accInvailds);
                result.put("vailds", accVailds);
                result.put("amount", accAmount);
                result.put("refundAmount", accRefundAmount);
            }
            results.add(result);
        }

        return results;
    }

    public List<Map<String, Object>> statActivityStatisticsByFunc(String orderBy) {
        StatisticsFuncEnum funcEnum = StatisticsFuncEnum.fromOrderBy(orderBy);
        if (funcEnum == null) {
            return Collections.emptyList();
        }
        List<Map<String, Object>> maps;
        if (funcEnum == StatisticsFuncEnum.DATE) {
            maps = statMapper.statActivityStatisticsByDate();
        } else if (funcEnum == StatisticsFuncEnum.WEEK) {
            maps = statMapper.statActivityStatisticsByWeek();
        } else if (funcEnum == StatisticsFuncEnum.MONTH) {
            maps = statMapper.statActivityStatisticsByMonth();
        } else if (funcEnum == StatisticsFuncEnum.QUARTER) {
            maps = statMapper.statActivityStatisticsByQuarter();
        } else if (funcEnum == StatisticsFuncEnum.YEAR) {
            maps = statMapper.statActivityStatisticsByYear();
        } else {
            maps = Collections.emptyList();
        }

        return maps;
    }

    public List<Map<String, Object>> statActivityOrderByFunc(String orderBy) {
        StatisticsFuncEnum funcEnum = StatisticsFuncEnum.fromOrderBy(orderBy);
        if (funcEnum == null) {
            return Collections.emptyList();
        }
        List<Map<String, Object>> ordersMapList;
        if (funcEnum == StatisticsFuncEnum.DATE) {
            ordersMapList = statMapper.statActivityOrdersByDate();
        } else if (funcEnum == StatisticsFuncEnum.WEEK) {
            ordersMapList = statMapper.statActivityOrdersByWeek();
        } else if (funcEnum == StatisticsFuncEnum.MONTH) {
            ordersMapList = statMapper.statActivityOrdersByMonth();

        } else if (funcEnum == StatisticsFuncEnum.QUARTER) {
            ordersMapList = statMapper.statActivityOrdersByQuarter();
        } else if (funcEnum == StatisticsFuncEnum.YEAR) {
            ordersMapList = statMapper.statActivityOrdersByYear();
        } else {
            return Collections.emptyList();
        }
        List<String> dates = ordersMapList.stream().map(it -> (String) it.get("date")).sorted().collect(Collectors.toList());
        List<Map<String, Object>> results = new ArrayList<>();
        for (int i = 0, index = dates.size(); i < index; i++) {
            String date = dates.get(i);
            Map<String, Object> result = new HashMap<>(16);

            Map<String, Object> totalMap = ordersMapList.get(i);
            result.put("date", date);
            result.put("orders", totalMap.get("orders"));
            result.put("invailds", totalMap.get("invailds"));
            result.put("vailds", totalMap.get("vailds"));
            result.put("amount", totalMap.get("amount"));
            result.put("refundAmount", totalMap.get("refundAmount"));

            results.add(result);
        }
        return results;
    }

}
